package tools;

import it.sauronsoftware.ftp4j.FTPAbortedException;
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPDataTransferException;
import it.sauronsoftware.ftp4j.FTPException;
import it.sauronsoftware.ftp4j.FTPFile;
import it.sauronsoftware.ftp4j.FTPIllegalReplyException;
import it.sauronsoftware.ftp4j.FTPListParseException;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.swing.UnsupportedLookAndFeelException;

import org.xml.sax.SAXException;

import main.Application;
import main.DatabaseManager;

/**
 * klasa do laczenia sie z serverem ftp, otwiera polaczenie w konstruktorze,
 * niestety nie trzyma tego polaczenia na trwale, zdycha na timeoucie po paru minutach,
 * wiec przy kazdym transferze plikow trzeba tworzyc nowa instancje connectora
 * 
 * @author acer
 *
 */

public class FTPConnector {
	
	FTPClient client;
	private static final String systemFileAttrib = "SystemFile";
	private static final String systemFileRootDir = "root";
	private enum UploadMode
	{
		SystemFile,
		FTP
	}
	
	UploadMode upMode;
	
	public FTPConnector() throws IllegalStateException, IOException, FTPIllegalReplyException, FTPException, SAXException, ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException
	{
		client = new FTPClient();
		
		BufferedReader reader = new BufferedReader(new FileReader("address.txt"));
		String address = reader.readLine();
		if(address.equals(systemFileAttrib))
			upMode = UploadMode.SystemFile;
		else
			upMode = UploadMode.FTP;	
		System.out.println(address);
		
	//	System.out.println(DatabaseManager.getInstance().getCurrentConnectionAttributes().getHost());
	//	client.connect(DatabaseManager.getInstance().getCurrentConnectionAttributes().getHost());
		
	//	client.setPassive(false);
		if(upMode.equals(UploadMode.FTP))
		{
			client.connect(address);		
			client.login(Application.getInstance().getFtpLogin(), Application.getInstance().getFtpPassword());
		}
		

	}
	/**
	 * rozlacza sie z ftpem, dobrzeby bylo wrzucic to gdzies razem z innymi rzeczami
	 * przy konczeniu dzialania aplikacji
	 * 
	 * @throws IllegalStateException
	 * @throws IOException
	 * @throws FTPIllegalReplyException
	 * @throws FTPException
	 */
	
	public void disconnect() throws IllegalStateException, IOException, FTPIllegalReplyException, FTPException
	{
		if(upMode.equals(UploadMode.FTP))
			client.disconnect(true);
	}
	
	/**
	 * wrzuca podany plik na server ftp
	 * 
	 * @param file plik do wrzucenia na ftp
	 * @param wydzial identyfikator wydzialu, i przy okazji nazwa katalogu na ftpie w ktorym bedzie siedzial plik
	 * @throws FTPException 
	 * @throws FTPIllegalReplyException 
	 * @throws IOException 
	 * @throws IllegalStateException 
	 * @throws FTPListParseException 
	 * @throws FTPAbortedException 
	 * @throws FTPDataTransferException 
	 */
	
	public void uploadFile(File file, String wydzial) throws IllegalStateException, IOException, FTPIllegalReplyException, FTPException, FTPDataTransferException, FTPAbortedException, FTPListParseException
	{
		if(upMode.equals(UploadMode.SystemFile))
		{
			uploadToSystemFile(file,wydzial);
			return;
		}
		client.changeDirectory("/ftproot");
		FTPFile[] dirlist = client.list();
		boolean found = false;
		for(int i = 0; i < dirlist.length; ++i)
		{
			if(dirlist[i].getName().equals(wydzial))
			{
				found = true;
				break;
			}
		}
		if(!found)
			client.createDirectory(wydzial);
		
		client.changeDirectory(wydzial);
		client.upload(file);
		
	}
	
	private void uploadToSystemFile(File file, String wydzial) throws IOException 
	{
		File rootDir = new File(systemFileRootDir);
		if(!rootDir.exists())
		{
			rootDir.mkdir();
		}
		String wydzialDirName = systemFileRootDir+"/"+ wydzial;
		File wydzialDir = new File(wydzialDirName);
		if(!wydzialDir.exists())
		{
			wydzialDir.mkdir();
		}			     
	    File dstFile = new File(wydzialDirName+"/" + file.getName());
	    coppyFile(file, dstFile);		
	}	
	
	public void coppyFile(File srcFile, File dstFile) throws IOException
	{
		InputStream in_ = new FileInputStream(srcFile);	    
		 OutputStream out_ = new FileOutputStream(dstFile);
		 
		 BufferedInputStream in = new BufferedInputStream(in_);
		 BufferedOutputStream out = new BufferedOutputStream(out_);

	      byte[] buf = new byte[1024];
	      int len;
	      while ((len = in.read(buf)) > 0){
	        out.write(buf, 0, len);
	      }
	      in.close();
	      out.close();
	}
	
	public void downloadFile(String filename, String wydzial, String downloadedFileName) throws IllegalStateException, IOException, FTPIllegalReplyException, FTPException, FTPDataTransferException, FTPAbortedException
	{
		if(upMode.equals(UploadMode.SystemFile))
		{
			uploadFromSystemFile(downloadedFileName,wydzial,filename);
			return;
		}
		
		client.changeDirectory("/ftproot/" + wydzial);
		client.download(filename, new File(downloadedFileName));
	}
	private void uploadFromSystemFile(String filename, String wydzial,String downloadedFileName) throws IOException 
	{
		String srcFileName =  systemFileRootDir+"/"+wydzial+"/"+downloadedFileName;
		File dstFile = new File(filename);
		File srcFile = new File(srcFileName);
		coppyFile(srcFile, dstFile);
		
	}
	
	public void moveFile(String oldDir, String newDir, String fileName) throws IllegalStateException, IOException, FTPIllegalReplyException, FTPException, FTPDataTransferException, FTPAbortedException, FTPListParseException
	{
		client.changeDirectory("/ftproot/");
		FTPFile[] dirlist = client.list();
		boolean found = false;
		for(int i = 0; i < dirlist.length; ++i)
		{
			if(dirlist[i].getName().equals(newDir))
			{
				found = true;
				break;
			}
		}
		if(!found)
			client.createDirectory(newDir);

		client.rename("/ftproot/" + oldDir + "/" + fileName, "/ftproot/" + newDir + "/" + fileName);
	}
	
	public void deleteFileIfExists(String wydzial, String nazwa) throws IllegalStateException, IOException, FTPIllegalReplyException, FTPException
	{
		client.deleteFile("/ftproot/" + wydzial + "/" + nazwa);
	}
}
